#include <iostream>
#include <random>
#include <sstream>
#include <QCoreApplication>
#include "autoPackage.h"
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QFileInfo>
#include <QProcess>
#ifdef Q_OS_LINUX
#include <QObject>
#endif

bool autoPackage::first = true;

int autoPackage::replaceAndCount(std::string& originalStr,const std::string& oldWord, const std::string& newWord) {

    if (oldWord.empty()) {
        return 0;
    }

    int replaceCount = 0;
    size_t start_pos = 0;

    while ((start_pos = originalStr.find(oldWord, start_pos)) != std::string::npos) {
        originalStr.replace(start_pos, oldWord.length(), newWord);
        start_pos += newWord.length();
        replaceCount++;
    }
    return replaceCount;
}

void autoPackage::outputFile(const std::string& originalStr,const std::string& outputPath,const std::string& appName) {
    QString qOutputPath = QString::fromStdString(outputPath);
    QString qAppName = QString::fromStdString(appName);
    QString qContent = QString::fromStdString(originalStr);

    QDir dir(qOutputPath);
    if (!dir.exists()) {
        if (!dir.mkpath(".")) {
            QMessageBox::critical(nullptr, "错误",
                                  QString("无法创建输出目录:\n%1").arg(qOutputPath));
            return;
        }
    }

    QString fileName = qAppName;
    if (!fileName.endsWith(".iss", Qt::CaseInsensitive)) {
        fileName += ".iss";
    }
    QString filePath = dir.filePath(fileName);

    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::critical(nullptr, "错误",
                              QString("无法创建文件:\n%1\n错误: %2")
                                  .arg(filePath)
                                  .arg(file.errorString()));
        return;
    }

    QTextStream out(&file);

    out << qContent;
    file.close();
}

std::string autoPackage::GenerateRFC4122Guid() {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, 15);  // 0x0~0xF
    std::uniform_int_distribution<> dis_variant(8, 11); // 8=0x8, 9=0x9, 10=0xA, 11=0xB

    std::stringstream ss;
    ss << "AppId={{";  // 固定前缀

    // 生成 8-4-4-4-12 的 GUID，符合 RFC 4122 版本 4
    for (int i = 0; i < 32; i++) {
        if (i == 8 || i == 12 || i == 16 || i == 20) {
            ss << "-";
        }

        // 根据 RFC 4122 设置固定位
        if (i == 12) {
            ss << "4";  // 版本 4
        } else if (i == 16) {
            ss << std::uppercase << std::hex << dis_variant(gen);  // 8,9,A,B
        } else {
            ss << std::uppercase << std::hex << dis(gen);  // 随机十六进制
        }
    }

    ss << "}";  // 固定后缀
    return ss.str();
}

void autoPackage::run(const std::string& myAppname,const std::string& myAppVersion,const std::string& exeName,const std::string& path,const std::string& outputPath) {
    std::string originalStr = META_STRING;
    replaceAndCount(originalStr,R"delimiter(#define MyAppName "ITE数据检查")delimiter", "#define MyAppName \""+myAppname+"\"");
    replaceAndCount(originalStr,R"delimiter(#define MyAppVersion "0.0.1")delimiter", "#define MyAppVersion \""+myAppVersion+"\"");
    replaceAndCount(originalStr,R"delimiter(#define MyAppExeName "ite_viewer.exe")delimiter", "#define MyAppExeName \""+exeName+".exe\"");
    replaceAndCount(originalStr,R"delimiter(AppId={{27682F4A-88E9-4642-BD7D-38B6F4DC3B10})delimiter", GenerateRFC4122Guid());
    replaceAndCount(originalStr,R"delimiter(DefaultDirName={autopf}\{#MyAppName})delimiter", "DefaultDirName={autopf}\\"+exeName);
    replaceAndCount(originalStr,R"delimiter(OutputBaseFilename=setup)delimiter", "OutputBaseFilename="+exeName+"_win_"+myAppVersion);
    replaceAndCount(originalStr,R"delimiter(OutputDir=C:\Users\TCT-GYC\Desktop\fast)delimiter", "OutputDir="+QDir::toNativeSeparators(QString::fromStdString(outputPath)).toStdString());
    
    // 使用正确的路径分隔符和引号
    std::string nativePath = QDir::toNativeSeparators(QString::fromStdString(path)).toStdString();
    replaceAndCount(originalStr,R"delimiter(C:\Users\TCT-GYC\Downloads\Tools_v0.0.1\Debug)delimiter", nativePath);

    // 设置图标文件路径 - 使用AutoPackage.exe目录中的图标
    std::string iconPath = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + "/icons/tct.ico").toStdString();
    replaceAndCount(originalStr,R"delimiter(SetupIconFile=C:\Users\TCT-GYC\Desktop\tct.ico)delimiter", "SetupIconFile="+iconPath);

    outputFile(originalStr,outputPath,myAppname);
}

#ifdef Q_OS_LINUX
void autoPackage::runAppImagePackaging(const std::string& appName, const std::string& appVersion, 
                                       const std::string& exeName, const std::string& appPath, 
                                       const std::string& iconPath, const std::string& outputPath,
                                       QObject* parent) {
    
    // 复制应用程序和图标文件到输出目录
    QString qAppPath = QString::fromStdString(appPath);
    QString qIconPath = QString::fromStdString(iconPath);
    QString qOutputPath = QString::fromStdString(outputPath);
    QString qAppName = QString::fromStdString(appName);
    
    // 创建以程序名命名的子输出目录
    QString subDirName = qAppName + "_output";
    QString actualOutputPath = QDir(qOutputPath).filePath(subDirName);
    
    // 确保子输出目录存在
    QDir outputDir(actualOutputPath);
    if (!outputDir.exists()) {
        outputDir.mkpath(".");
    }
    
    // 复制应用程序到输出目录
    QFileInfo appFileInfo(qAppPath);
    QString targetAppPath = outputDir.filePath(qAppName);
    
    // 如果目标文件已存在，先删除
    if (QFile::exists(targetAppPath)) {
        QFile::remove(targetAppPath);
    }
    
    if (!QFile::copy(qAppPath, targetAppPath)) {
        QMessageBox::critical(nullptr, "错误", 
            QString("无法复制应用程序文件到输出目录:\n%1").arg(targetAppPath));
        return;
    }
    
    // 设置可执行权限
    QFile::setPermissions(targetAppPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner |
                                        QFile::ReadGroup | QFile::ExeGroup |
                                        QFile::ReadOther | QFile::ExeOther);
    
    // 复制图标文件到输出目录
    QFileInfo iconFileInfo(qIconPath);
    QString iconExtension = iconFileInfo.suffix();
    QString targetIconPath = outputDir.filePath(qAppName + "." + iconExtension);
    
    if (QFile::exists(targetIconPath)) {
        QFile::remove(targetIconPath);
    }
    
    if (!QFile::copy(qIconPath, targetIconPath)) {
        QMessageBox::critical(nullptr, "错误", 
            QString("无法复制图标文件到输出目录:\n%1").arg(targetIconPath));
        return;
    }
    
    // 创建临时AppImage打包脚本
    QString scriptPath = outputDir.filePath("temp_create_appimage.sh");
    createAppImageScript(scriptPath);
    
    // 确保脚本有执行权限
    QFile::setPermissions(scriptPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner |
                                     QFile::ReadGroup | QFile::ExeGroup |
                                     QFile::ReadOther | QFile::ExeOther);
    
    // 创建并运行打包脚本
    QProcess *packagingProcess = new QProcess();
    
    // 设置工作目录为子输出目录
    packagingProcess->setWorkingDirectory(actualOutputPath);
    
    // 准备命令参数
    QStringList arguments;
    arguments << qAppName << (qAppName + "." + iconExtension) << QString::fromStdString(appVersion);
    
    // 异步执行打包脚本
    QObject::connect(packagingProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
        [packagingProcess, actualOutputPath, scriptPath, parent](int exitCode, QProcess::ExitStatus exitStatus) {
            
        // 清理临时脚本文件
        QFile::remove(scriptPath);
        
        if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
            // 打包成功，清理所有非AppImage文件和文件夹
            QDir outputDir(actualOutputPath);
            
            // 获取所有条目（文件和文件夹）
            QStringList allEntries = outputDir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
            
            for (const QString &entryName : allEntries) {
                if (!entryName.endsWith(".AppImage")) {
                    QString entryPath = outputDir.filePath(entryName);
                    QFileInfo entryInfo(entryPath);
                    
                    if (entryInfo.isDir()) {
                        // 删除文件夹及其内容
                        QDir dir(entryPath);
                        if (dir.removeRecursively()) {
                            qDebug() << "已删除临时文件夹:" << entryPath;
                        }
                    } else {
                        // 删除文件
                        if (QFile::remove(entryPath)) {
                            qDebug() << "已删除临时文件:" << entryPath;
                        }
                    }
                }
            }
        }
        
        // 通过parent发送信号来通知UI完成状态
        if (parent) {
            if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
                // 发送成功信号
                QMetaObject::invokeMethod(parent, "onAppImagePackagingFinished", 
                    Q_ARG(bool, true), Q_ARG(QString, actualOutputPath), Q_ARG(QString, ""));
            } else {
                // 发送失败信号
                QString errorOutput = packagingProcess->readAllStandardError();
                QString stdOutput = packagingProcess->readAllStandardOutput();
                QString errorMsg = QString("AppImage 打包失败！\n\n错误信息：\n%1\n\n输出信息：\n%2")
                    .arg(errorOutput).arg(stdOutput);
                QMetaObject::invokeMethod(parent, "onAppImagePackagingFinished", 
                    Q_ARG(bool, false), Q_ARG(QString, actualOutputPath), Q_ARG(QString, errorMsg));
            }
        }
        
        packagingProcess->deleteLater();
    });
    
    // 启动打包过程
    packagingProcess->start(scriptPath, arguments);
    
    if (!packagingProcess->waitForStarted()) {
        QMessageBox::critical(nullptr, "错误", 
            "无法启动AppImage打包脚本！\n请检查脚本文件权限和依赖工具是否已安装。");
        packagingProcess->deleteLater();
        QFile::remove(scriptPath); // 清理临时文件
        return;
    }
}

void autoPackage::createAppImageScript(const QString& scriptPath) {
    // 嵌入的AppImage打包脚本内容
    const QString scriptContent = R"SCRIPT(#!/bin/bash

# ==============================================
# 通用 Qt AppImage 打包脚本（含自动桌面集成）
# 使用方法: ./create_qt_appimage.sh [应用程序名] [图标文件]
# ==============================================

set -e  # 遇到错误立即退出

# --- 参数检查 ---
if [ $# -ne 3 ]; then
    echo "❌ 用法: $0 [应用程序名] [图标文件.svg/.png/.ico] [版本号]"
    echo "例如: $0 MyApp MyApp.svg 1.0.0"
    exit 1
fi

APP_NAME="$1"
ICON_FILE="$2"
VERSION="$3"
OUTPUT_FILE="${APP_NAME}_ubuntu_${VERSION}.AppImage"

echo "🚀 开始打包 Qt 应用程序..."
echo "📱 应用名称: $APP_NAME"
echo "🎨 图标文件: $ICON_FILE"
echo ""

# --- 验证文件和工具 ---
[ ! -f "$ICON_FILE" ] && echo "❌ 错误：图标文件不存在！" && exit 1
[ ! -f "$APP_NAME" ] && echo "❌ 错误：可执行文件 $APP_NAME 不存在！" && exit 1

command -v linuxdeployqt >/dev/null 2>&1 || { echo "❌ 错误：需要安装 linuxdeployqt"; exit 1; }

# 查找qmake
QMAKE_PATH=""
for qmake_candidate in "/opt/Qt/6.9.0/gcc_64/bin/qmake6" "/usr/bin/qmake6" "/usr/bin/qmake-qt6" "/usr/bin/qmake"; do
    if [ -f "$qmake_candidate" ]; then
        QMAKE_PATH="$qmake_candidate"
        break
    fi
done

[ -z "$QMAKE_PATH" ] && echo "❌ 错误：未找到 qmake" && exit 1
echo "✅ 找到 qmake: $QMAKE_PATH"

# --- 清理旧文件 ---
rm -rf *.AppImage squashfs-root 2>/dev/null || true

# --- 1. 先创建自定义 AppRun 脚本 ---
echo "📝 创建自定义 AppRun 脚本..."
cat > AppRun << 'APPRUN_EOF'
#!/bin/bash
set -e

HERE="$(dirname "$(readlink -f "${0}")")"

# 设置环境变量
export LD_LIBRARY_PATH="$HERE/lib:${LD_LIBRARY_PATH}"
export QT_PLUGIN_PATH="$HERE/plugins:${QT_PLUGIN_PATH}"
export PATH="$HERE:$PATH"
export XDG_DATA_DIRS="$HERE/usr/share:${XDG_DATA_DIRS}"

# 获取应用名称
APPNAME="APP_NAME_PLACEHOLDER"

# 桌面集成（每次运行时强制更新）
echo "🔗 正在强制更新桌面集成..."

# 创建必要目录
APPS_DIR="$HOME/.local/share/applications"
ICON_DIR="$HOME/.local/share/icons/hicolor/256x256/apps"
mkdir -p "$APPS_DIR" "$ICON_DIR"

# 复制图标（强制覆盖）
ICON_COPIED=false
for icon_ext in svg png ico; do
    if [ -f "$HERE/$APPNAME.$icon_ext" ]; then
        cp "$HERE/$APPNAME.$icon_ext" "$ICON_DIR/$APPNAME.$icon_ext"
        echo "📎 图标已强制更新: $APPNAME.$icon_ext"
        ICON_COPIED=true
        break
    fi
done

# 获取 AppImage 路径
APPIMAGE_PATH="$APPIMAGE"
[ -z "$APPIMAGE_PATH" ] && APPIMAGE_PATH=$(readlink -f "/proc/$$/exe" 2>/dev/null || echo "")

# 强制创建/更新应用程序菜单项
if [ -n "$APPIMAGE_PATH" ]; then
    cat > "$APPS_DIR/$APPNAME.desktop" << DESKTOP_EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=$APPNAME
Comment=$APPNAME Application
Exec="$APPIMAGE_PATH"
Icon=$APPNAME
Categories=Utility;
Terminal=false
StartupNotify=true
DESKTOP_EOF
    chmod +x "$APPS_DIR/$APPNAME.desktop"
    echo "📋 应用菜单项已强制更新"
    
    # 强制创建/更新桌面快捷方式
    for desktop_dir in "$HOME/Desktop" "$HOME/桌面" "$HOME/desktop"; do
        if [ -d "$desktop_dir" ]; then
            DESKTOP_FILE="$desktop_dir/$APPNAME.desktop"
            cat > "$DESKTOP_FILE" << DESKTOP_FILE_EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=$APPNAME
Comment=$APPNAME Application
Exec="$APPIMAGE_PATH"
Icon=$APPNAME
Categories=Utility;
Terminal=false
StartupNotify=true
DESKTOP_FILE_EOF
                chmod 755 "$DESKTOP_FILE"
                
                # 设置为可信任
                if command -v gio >/dev/null 2>&1; then
                    gio set "$DESKTOP_FILE" metadata::trusted true 2>/dev/null || true
                fi
                
                echo "🖥️  桌面快捷方式已创建: $DESKTOP_FILE"
                break
            fi
        done
        
        # 更新缓存
        if command -v gtk-update-icon-cache >/dev/null 2>&1; then
            gtk-update-icon-cache "$HOME/.local/share/icons/hicolor" 2>/dev/null || true
            echo "🔄 图标缓存已更新"
        fi
        
        if command -v update-desktop-database >/dev/null 2>&1; then
            update-desktop-database "$APPS_DIR" 2>/dev/null || true
            echo "🔄 桌面数据库已更新"
        fi
        
    echo "✅ 桌面集成完成！"
fi

# 启动应用程序
APP_EXECUTABLE="$HERE/$APPNAME"
if [ -x "$APP_EXECUTABLE" ]; then
    exec "$APP_EXECUTABLE" "$@"
else
    echo "❌ 错误：找不到可执行文件 $APPNAME"
    exit 1
fi
APPRUN_EOF

# 替换占位符
sed -i "s/APP_NAME_PLACEHOLDER/$APP_NAME/g" AppRun

chmod +x AppRun
echo "✅ 自定义 AppRun 已创建"

# --- 2. 创建 .desktop 文件 ---
echo "📋 创建 .desktop 文件..."
cat > "${APP_NAME}.desktop" << DESKTOP_EOF
[Desktop Entry]
Version=1.0
Name=$APP_NAME
Comment=$APP_NAME Application
Exec=$APP_NAME
Icon=$APP_NAME
Type=Application
Categories=Utility;
Terminal=false
StartupNotify=true
DESKTOP_EOF

# --- 3. 使用 linuxdeployqt 打包（它会使用我们的 AppRun）---
echo "📦 使用 linuxdeployqt 打包应用..."
if linuxdeployqt "$APP_NAME" -appimage -qmake="$QMAKE_PATH"; then
    echo "✅ linuxdeployqt 打包成功"
else
    echo "❌ linuxdeployqt 打包失败"
    exit 1
fi

# --- 4. 查找并重命名生成的 AppImage 文件 ---
GENERATED_APPIMAGE=$(ls *.AppImage 2>/dev/null | head -1)
if [ -z "$GENERATED_APPIMAGE" ]; then
    echo "❌ 错误：未找到生成的 AppImage 文件"
    exit 1
fi

# 重命名为更友好的名称
mv "$GENERATED_APPIMAGE" "$OUTPUT_FILE"
echo "📁 AppImage 重命名为: $OUTPUT_FILE"

# --- 5. 清理临时文件 ---
rm -rf "${APP_NAME}.desktop" AppRun 2>/dev/null || true

# --- 最终检查和输出 ---
if [ -f "$OUTPUT_FILE" ]; then
    chmod +x "$OUTPUT_FILE"
    FILE_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1)
    
    echo ""
    echo "🎉 ========================================"
    echo "✅ AppImage 创建成功！"
    echo "======================================== 🎉"
    echo ""
    echo "📁 输出文件: $(pwd)/$OUTPUT_FILE"
    echo "📊 文件大小: $FILE_SIZE"
    echo "🎨 包含图标: $ICON_FILE"
    echo ""
    echo "🚀 分发说明："
    echo "1. 将 $OUTPUT_FILE 发送给用户"
    echo "2. 用户双击运行即可（首次会自动设置桌面集成）"
    echo "3. 桌面和程序菜单会自动出现 $APP_NAME 图标"
    echo "4. 之后可以直接双击桌面图标或从程序菜单启动"
    echo ""
    echo "💡 用户使用步骤："
    echo "   1. 下载 $OUTPUT_FILE 到任意目录"  
    echo "   2. 双击运行（如需要：右键 → 属性 → 权限 → 勾选'允许执行'）"
    echo "   3. 首次运行会自动创建桌面快捷方式和程序菜单项"
    echo "   4. 之后可直接双击桌面上的 $APP_NAME 图标启动"
    echo ""
    echo "✨ 只需要发送这一个文件！用户体验完美！"
else
    echo "❌ 创建失败！"
    exit 1
fi
)SCRIPT";
    
    QFile file(scriptPath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::critical(nullptr, "错误", 
            QString("无法创建临时脚本文件:\n%1").arg(scriptPath));
        return;
    }
    
    QTextStream out(&file);
    out << scriptContent;
    file.close();
}

void autoPackage::runNonQtAppImagePackaging(const std::string& appName, const std::string& appVersion, 
                                           const std::string& exeName, const std::string& appPath, 
                                           const std::string& iconPath, const std::string& outputPath,
                                           QObject* parent) {
    
    // 复制应用程序和图标文件到输出目录
    QString qAppPath = QString::fromStdString(appPath);
    QString qIconPath = QString::fromStdString(iconPath);
    QString qOutputPath = QString::fromStdString(outputPath);
    QString qAppName = QString::fromStdString(appName);
    
    // 创建以程序名命名的子输出目录
    QString subDirName = qAppName + "_output";
    QString actualOutputPath = QDir(qOutputPath).filePath(subDirName);
    
    // 确保子输出目录存在
    QDir outputDir(actualOutputPath);
    if (!outputDir.exists()) {
        outputDir.mkpath(".");
    }
    
    // 复制应用程序到输出目录
    QFileInfo appFileInfo(qAppPath);
    QString targetAppPath = outputDir.filePath(qAppName);
    
    // 如果目标文件已存在，先删除
    if (QFile::exists(targetAppPath)) {
        QFile::remove(targetAppPath);
    }
    
    if (!QFile::copy(qAppPath, targetAppPath)) {
        QMessageBox::critical(nullptr, "错误", 
            QString("无法复制应用程序文件到输出目录:\n%1").arg(targetAppPath));
        return;
    }
    
    // 设置可执行权限
    QFile::setPermissions(targetAppPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner |
                                        QFile::ReadGroup | QFile::ExeGroup |
                                        QFile::ReadOther | QFile::ExeOther);
    
    // 复制图标文件到输出目录
    QFileInfo iconFileInfo(qIconPath);
    QString iconExtension = iconFileInfo.suffix();
    QString targetIconPath = outputDir.filePath(qAppName + "." + iconExtension);
    
    if (QFile::exists(targetIconPath)) {
        QFile::remove(targetIconPath);
    }
    
    if (!QFile::copy(qIconPath, targetIconPath)) {
        QMessageBox::critical(nullptr, "错误", 
            QString("无法复制图标文件到输出目录:\n%1").arg(targetIconPath));
        return;
    }
    
    // 创建临时非Qt AppImage打包脚本
    QString scriptPath = outputDir.filePath("temp_create_nonqt_appimage.sh");
    createNonQtAppImageScript(scriptPath);
    
    // 确保脚本有执行权限
    QFile::setPermissions(scriptPath, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner |
                                     QFile::ReadGroup | QFile::ExeGroup |
                                     QFile::ReadOther | QFile::ExeOther);
    
    // 创建并运行打包脚本
    QProcess *packagingProcess = new QProcess();
    
    // 设置工作目录为子输出目录
    packagingProcess->setWorkingDirectory(actualOutputPath);
    
    // 准备命令参数 - 传递原始完整路径以保持项目结构
    QStringList arguments;
    arguments << qAppPath << qIconPath << QString::fromStdString(appVersion);
    
    // 异步执行打包脚本
    QObject::connect(packagingProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
        [packagingProcess, actualOutputPath, scriptPath, parent](int exitCode, QProcess::ExitStatus exitStatus) {
            
        // 清理临时脚本文件
        QFile::remove(scriptPath);
        
        if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
            // 打包成功，清理所有非AppImage文件和文件夹
            QDir outputDir(actualOutputPath);
            
            // 获取所有条目（文件和文件夹）
            QStringList allEntries = outputDir.entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
            
            for (const QString &entryName : allEntries) {
                if (!entryName.endsWith(".AppImage")) {
                    QString entryPath = outputDir.filePath(entryName);
                    QFileInfo entryInfo(entryPath);
                    
                    if (entryInfo.isDir()) {
                        // 删除文件夹及其内容
                        QDir dir(entryPath);
                        if (dir.removeRecursively()) {
                            qDebug() << "已删除临时文件夹:" << entryPath;
                        }
                    } else {
                        // 删除文件
                        if (QFile::remove(entryPath)) {
                            qDebug() << "已删除临时文件:" << entryPath;
                        }
                    }
                }
            }
        }
        
        // 通过parent发送信号来通知UI完成状态
        if (parent) {
            if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
                // 发送成功信号
                QMetaObject::invokeMethod(parent, "onAppImagePackagingFinished", 
                    Q_ARG(bool, true), Q_ARG(QString, actualOutputPath), Q_ARG(QString, ""));
            } else {
                // 发送失败信号
                QString errorOutput = packagingProcess->readAllStandardError();
                QString stdOutput = packagingProcess->readAllStandardOutput();
                QString errorMsg = QString("AppImage 打包失败！\n\n错误信息：\n%1\n\n输出信息：\n%2")
                    .arg(errorOutput).arg(stdOutput);
                QMetaObject::invokeMethod(parent, "onAppImagePackagingFinished", 
                    Q_ARG(bool, false), Q_ARG(QString, actualOutputPath), Q_ARG(QString, errorMsg));
            }
        }
        
        packagingProcess->deleteLater();
    });
    
    // 启动打包过程
    packagingProcess->start(scriptPath, arguments);
    
    if (!packagingProcess->waitForStarted()) {
        QMessageBox::critical(nullptr, "错误", 
            "无法启动AppImage打包脚本！\n请检查脚本文件权限和依赖工具是否已安装。");
        packagingProcess->deleteLater();
        QFile::remove(scriptPath); // 清理临时文件
        return;
    }
}

void autoPackage::createNonQtAppImageScript(const QString& scriptPath) {
    // 嵌入的非Qt应用AppImage打包脚本内容
    const QString scriptContent = R"SCRIPT(#!/bin/bash

# ==============================================
# 非Qt应用 AppImage 打包脚本（含自动桌面集成）
# 使用方法: ./create_nonqt_appimage.sh [应用程序名] [图标文件]
# ==============================================

set -e  # 遇到错误立即退出

# --- 参数检查 ---
if [ $# -ne 3 ]; then
    echo "❌ 用法: $0 [应用程序名] [图标文件.svg/.png/.ico] [版本号]"
    echo "例如: $0 MyApp MyApp.svg 1.0.0"
    exit 1
fi

APP_NAME="$1"
ICON_FILE="$2"
VERSION="$3"

# 获取可执行文件的基本名称用于输出文件名
APP_BASE_NAME=$(basename "$APP_NAME")
OUTPUT_FILE="${APP_BASE_NAME}_ubuntu_${VERSION}.AppImage"
APPDIR="${APP_BASE_NAME}.AppDir"

echo "🚀 开始打包非Qt应用程序..."
echo "📱 应用名称: $APP_NAME"
echo "🎨 图标文件: $ICON_FILE"
echo ""

# --- 验证文件和工具 ---
[ ! -f "$ICON_FILE" ] && echo "❌ 错误：图标文件不存在！" && exit 1
[ ! -f "$APP_NAME" ] && echo "❌ 错误：可执行文件 $APP_NAME 不存在！" && exit 1

command -v appimagetool >/dev/null 2>&1 || { echo "❌ 错误：需要安装 appimagetool"; exit 1; }

# --- 清理旧文件 ---
rm -rf *.AppImage "$APPDIR" 2>/dev/null || true

# --- 1. 创建 AppDir 结构 ---
echo "📁 创建 AppDir 结构..."
mkdir -p "$APPDIR/usr/bin"
mkdir -p "$APPDIR/usr/share/applications"
mkdir -p "$APPDIR/usr/share/icons/hicolor/16x16/apps"
mkdir -p "$APPDIR/usr/share/icons/hicolor/32x32/apps"
mkdir -p "$APPDIR/usr/share/icons/hicolor/48x48/apps"
mkdir -p "$APPDIR/usr/share/icons/hicolor/64x64/apps"
mkdir -p "$APPDIR/usr/share/icons/hicolor/128x128/apps"
mkdir -p "$APPDIR/usr/share/icons/hicolor/256x256/apps"
mkdir -p "$APPDIR/usr/share/icons/hicolor/512x512/apps"
mkdir -p "$APPDIR/usr/share/icons/hicolor/scalable/apps"
mkdir -p "$APPDIR/usr/share/pixmaps"

# --- 2. 复制应用程序和所有依赖文件 ---
echo "📦 复制应用程序和依赖文件..."

# 获取可执行文件的完整路径
APP_FULL_PATH=$(readlink -f "$APP_NAME")
APP_DIR=$(dirname "$APP_FULL_PATH")
# APP_BASE_NAME 已经在前面定义过了

echo "📁 应用程序完整路径: $APP_FULL_PATH"
echo "📁 应用程序目录: $APP_DIR"
echo "📁 可执行文件名: $APP_BASE_NAME"

# 检查应用程序结构和复制策略
if [[ "$APP_NAME" == */* ]]; then
    # 用户提供了路径，说明可执行文件在某个目录中
    echo "📦 检测到路径中的可执行文件，将复制整个应用目录..."
    
    mkdir -p "$APPDIR/opt"
    APP_BUNDLE_NAME="${APP_BASE_NAME}_bundle"
    mkdir -p "$APPDIR/opt/$APP_BUNDLE_NAME"
    
    # 检查并复制同目录下可能的依赖文件（但排除常见系统目录）
    SYSTEM_DIRS="/bin /sbin /usr/bin /usr/sbin /usr/local/bin /opt"
    IS_SYSTEM_DIR=false
    for sys_dir in $SYSTEM_DIRS; do
        if [[ "$APP_DIR" == "$sys_dir"* ]]; then
            IS_SYSTEM_DIR=true
            break
        fi
    done
    
    if [ "$IS_SYSTEM_DIR" = false ]; then
        echo "📦 检测到非系统目录，复制完整的项目目录..."
        echo "🔍 调试信息：APP_DIR=$APP_DIR"
        echo "🔍 调试信息：APP_BUNDLE_NAME=$APP_BUNDLE_NAME"
        echo "🔍 调试信息：目标目录=$APPDIR/opt/$APP_BUNDLE_NAME/"
        
        # 使用简单有效的方法：复制整个项目目录的所有内容
        # 这样可以确保所有依赖文件、子目录都被正确复制
        if [ -d "$APP_DIR" ]; then
            echo "📁 从 $APP_DIR 复制所有内容到 $APPDIR/opt/$APP_BUNDLE_NAME/"
            echo "🔍 源目录内容："
            ls -la "$APP_DIR"
            
            # 像手动脚本一样：直接复制整个目录内容
            echo "🔍 开始执行：cp -r \"$APP_DIR\"/* \"$APPDIR/opt/$APP_BUNDLE_NAME/\""
            cp -r "$APP_DIR"/* "$APPDIR/opt/$APP_BUNDLE_NAME/" 2>/dev/null || {
                echo "⚠️  使用通配符复制失败，尝试逐个复制..."
                # 如果通配符失败，逐个复制（处理特殊字符文件名）
                find "$APP_DIR" -maxdepth 1 \( ! -name ".*" \) \( ! -path "$APP_DIR" \) \
                    -exec cp -r {} "$APPDIR/opt/$APP_BUNDLE_NAME/" \; 2>/dev/null || true
            }
            # 确保主可执行文件有执行权限
            chmod +x "$APPDIR/opt/$APP_BUNDLE_NAME/$APP_BASE_NAME"
            
            echo "🔍 复制后目标目录内容："
            ls -la "$APPDIR/opt/$APP_BUNDLE_NAME/"
            echo "✅ 已复制完整的项目目录，包含所有文件和子目录"
        else
            echo "⚠️  目录不存在: $APP_DIR"
        fi
    else
        echo "📦 检测到系统目录，仅复制可执行文件"
        # 只复制可执行文件（系统目录）
        cp "$APP_FULL_PATH" "$APPDIR/opt/$APP_BUNDLE_NAME/$APP_BASE_NAME"
        chmod +x "$APPDIR/opt/$APP_BUNDLE_NAME/$APP_BASE_NAME"
    fi
elif [ -f "$APP_NAME" ]; then
    # 用户只提供了文件名，文件在当前目录
    echo "📦 检测到当前目录中的可执行文件..."
    mkdir -p "$APPDIR/opt"
    APP_BUNDLE_NAME="${APP_BASE_NAME}_bundle"
    mkdir -p "$APPDIR/opt/$APP_BUNDLE_NAME"
    
    cp "$APP_FULL_PATH" "$APPDIR/opt/$APP_BUNDLE_NAME/$APP_BASE_NAME"
    chmod +x "$APPDIR/opt/$APP_BUNDLE_NAME/$APP_BASE_NAME"
    
    echo "✅ 已复制可执行文件"
else
    echo "❌ 错误：无法找到可执行文件 $APP_NAME"
    exit 1
fi

echo "✅ 应用程序和相关文件已复制完成"

# 在usr/bin下创建启动脚本，指向opt目录中的实际程序
mkdir -p "$APPDIR/usr/bin"

# 创建启动脚本，使用基本文件名而不是完整路径
cat > "$APPDIR/usr/bin/$APP_BASE_NAME" << LAUNCHER_EOF
#!/bin/bash
# 获取 AppImage 的挂载根目录
APPIMAGE_ROOT="\$(dirname "\$(dirname "\$(dirname "\$(readlink -f "\${0}")")")")"

# 如果在AppImage中运行，APPDIR环境变量会指向挂载点
if [ -n "\$APPDIR" ]; then
    APPIMAGE_ROOT="\$APPDIR"
fi

APP_ROOT="\$APPIMAGE_ROOT/opt/${APP_BASE_NAME}_bundle"

# 调试信息（可选，用于排查问题）
# echo "Debug: Script path: \$(readlink -f "\${0}")" >&2
# echo "Debug: APPIMAGE_ROOT: \$APPIMAGE_ROOT" >&2
# echo "Debug: APP_ROOT: \$APP_ROOT" >&2

# 检查目录是否存在
if [ ! -d "\$APP_ROOT" ]; then
    echo "Error: Cannot find application directory: \$APP_ROOT" >&2
    echo "Available directories in \$APPIMAGE_ROOT:" >&2
    ls -la "\$APPIMAGE_ROOT" >&2 2>/dev/null || true
    echo "Available directories in \$APPIMAGE_ROOT/opt:" >&2
    ls -la "\$APPIMAGE_ROOT/opt" >&2 2>/dev/null || true
    exit 1
fi

# 切换到应用目录
if ! cd "\$APP_ROOT"; then
    echo "Error: Cannot change to application directory: \$APP_ROOT" >&2
    exit 1
fi

# 执行程序
exec "./$APP_BASE_NAME" "\$@"
LAUNCHER_EOF
chmod +x "$APPDIR/usr/bin/$APP_BASE_NAME"

# 在根目录也创建一个链接
ln -sf "usr/bin/$APP_BASE_NAME" "$APPDIR/$APP_BASE_NAME"

echo "✅ 应用程序目录已完整复制，包含所有依赖文件"

# --- 3. 处理图标文件 ---
echo "🎨 处理图标文件..."
ICON_EXT="${ICON_FILE##*.}"
MAIN_ICON_EXT="$ICON_EXT"

# appimagetool对图标格式有要求，如果是ico格式需要特殊处理
if [ "$ICON_EXT" = "ico" ]; then
    # 检查是否有convert命令（ImageMagick）来转换ico到png
    if command -v convert >/dev/null 2>&1; then
        echo "🔄 检测到ICO格式，正在转换为PNG格式..."
        convert "$ICON_FILE" "$APP_BASE_NAME.png" 2>/dev/null || {
            echo "⚠️  ICO转换失败，将直接使用ICO格式"
            MAIN_ICON_EXT="ico"
        }
        if [ -f "$APP_BASE_NAME.png" ]; then
            MAIN_ICON_EXT="png"
            echo "✅ ICO已转换为PNG"
        fi
    else
        echo "⚠️  未找到ImageMagick convert命令，将直接使用ICO格式"
        # 为兼容性创建一个png副本（实际上是ico文件）
        cp "$ICON_FILE" "$APP_BASE_NAME.png"
        MAIN_ICON_EXT="png"
    fi
fi

# 根据主图标格式设置正确的文件
if [ "$MAIN_ICON_EXT" = "png" ]; then
    MAIN_ICON_FILE="$APP_BASE_NAME.png"
else
    MAIN_ICON_FILE="$ICON_FILE"
fi

# 复制到根目录（appimagetool需要这个）
cp "$MAIN_ICON_FILE" "$APPDIR/$APP_BASE_NAME.$MAIN_ICON_EXT"

# 如果我们有png格式的图标，优先使用它作为主图标
if [ "$MAIN_ICON_EXT" = "png" ] && [ -f "$MAIN_ICON_FILE" ]; then
    # PNG图标复制到所有尺寸目录
    for size in 16x16 32x32 48x48 64x64 128x128 256x256 512x512; do
        cp "$MAIN_ICON_FILE" "$APPDIR/usr/share/icons/hicolor/$size/apps/$APP_BASE_NAME.png"
    done
    # 复制到pixmaps目录
    cp "$MAIN_ICON_FILE" "$APPDIR/usr/share/pixmaps/$APP_BASE_NAME.png"
    # .DirIcon文件
    cp "$MAIN_ICON_FILE" "$APPDIR/.DirIcon"
elif [ "$ICON_EXT" = "svg" ]; then
    # SVG图标复制到scalable目录
    cp "$ICON_FILE" "$APPDIR/usr/share/icons/hicolor/scalable/apps/$APP_BASE_NAME.svg"
    # 复制到pixmaps目录
    cp "$ICON_FILE" "$APPDIR/usr/share/pixmaps/$APP_BASE_NAME.svg"
    # .DirIcon文件
    cp "$ICON_FILE" "$APPDIR/.DirIcon"
else
    # 其他格式图标（包括ico）
    for size in 16x16 32x32 48x48 64x64 128x128 256x256 512x512; do
        cp "$ICON_FILE" "$APPDIR/usr/share/icons/hicolor/$size/apps/$APP_BASE_NAME.$ICON_EXT"
    done
    # 复制到pixmaps目录
    cp "$ICON_FILE" "$APPDIR/usr/share/pixmaps/$APP_BASE_NAME.$ICON_EXT"
    # .DirIcon文件
    cp "$ICON_FILE" "$APPDIR/.DirIcon"
fi

echo "✅ 图标文件已复制到所有必要位置"

# --- 4. 创建 desktop 文件 ---
echo "📋 创建 desktop 文件..."
cat > "$APPDIR/usr/share/applications/$APP_BASE_NAME.desktop" << DESKTOP_EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=$APP_BASE_NAME
Comment=$APP_BASE_NAME Application
Exec=$APP_BASE_NAME
Icon=$APP_BASE_NAME
Categories=Utility;
Terminal=false
StartupNotify=true
DESKTOP_EOF

# 在根目录也创建一个desktop文件
cp "$APPDIR/usr/share/applications/$APP_BASE_NAME.desktop" "$APPDIR/$APP_BASE_NAME.desktop"

echo "✅ Desktop 文件已创建"

# --- 5. 创建自定义 AppRun 脚本 ---
echo "📝 创建自定义 AppRun 脚本..."
cat > "$APPDIR/AppRun" << 'APPRUN_EOF'
#!/bin/bash
set -e

HERE="$(dirname "$(readlink -f "${0}")")"

# 设置环境变量
export LD_LIBRARY_PATH="$HERE/lib:$HERE/usr/lib:${LD_LIBRARY_PATH}"
export PATH="$HERE/usr/bin:$HERE:$PATH"
export XDG_DATA_DIRS="$HERE/usr/share:${XDG_DATA_DIRS}"

# 获取应用名称
APPNAME="APP_NAME_PLACEHOLDER"

# 桌面集成（每次运行时强制更新）
echo "🔗 正在强制更新桌面集成..."

# 创建必要目录
APPS_DIR="$HOME/.local/share/applications"
mkdir -p "$APPS_DIR"

# 创建图标目录
for size in 16x16 32x32 48x48 64x64 128x128 256x256 512x512 scalable; do
    mkdir -p "$HOME/.local/share/icons/hicolor/$size/apps"
done

# 复制图标文件（强制覆盖）
ICON_COPIED=false
for icon_ext in svg png ico jpg jpeg; do
    if [ -f "$HERE/$APPNAME.$icon_ext" ]; then
        # 根据文件类型复制到合适的目录
        if [ "$icon_ext" = "svg" ]; then
                cp "$HERE/$APPNAME.$icon_ext" "$HOME/.local/share/icons/hicolor/scalable/apps/$APPNAME.$icon_ext"
            else
                # 位图图标复制到所有尺寸目录
                for size in 16x16 32x32 48x48 64x64 128x128 256x256 512x512; do
                    cp "$HERE/$APPNAME.$icon_ext" "$HOME/.local/share/icons/hicolor/$size/apps/$APPNAME.$icon_ext"
                done
            fi
            echo "📎 图标已安装: $APPNAME.$icon_ext"
            ICON_COPIED=true
            break
        fi
    done
    
    # 获取 AppImage 路径
    APPIMAGE_PATH="$APPIMAGE"
    [ -z "$APPIMAGE_PATH" ] && APPIMAGE_PATH=$(readlink -f "/proc/$$/exe" 2>/dev/null || echo "")
    
    # 创建应用程序菜单项
    if [ -n "$APPIMAGE_PATH" ]; then
        cat > "$APPS_DIR/$APPNAME.desktop" << DESKTOP_EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=$APPNAME
Comment=$APPNAME Application
Exec="$APPIMAGE_PATH"
Icon=$APPNAME
Categories=Utility;
Terminal=false
StartupNotify=true
DESKTOP_EOF
    chmod +x "$APPS_DIR/$APPNAME.desktop"
    echo "📋 应用菜单项已强制更新"
    
    # 强制创建/更新桌面快捷方式
    for desktop_dir in "$HOME/Desktop" "$HOME/桌面" "$HOME/desktop"; do
        if [ -d "$desktop_dir" ]; then
            DESKTOP_FILE="$desktop_dir/$APPNAME.desktop"
            cat > "$DESKTOP_FILE" << DESKTOP_FILE_EOF
[Desktop Entry]
Version=1.0
Type=Application
Name=$APPNAME
Comment=$APPNAME Application
Exec="$APPIMAGE_PATH"
Icon=$APPNAME
Categories=Utility;
Terminal=false
StartupNotify=true
DESKTOP_FILE_EOF
            chmod 755 "$DESKTOP_FILE"
            
            # 设置为可信任
            if command -v gio >/dev/null 2>&1; then
                gio set "$DESKTOP_FILE" metadata::trusted true 2>/dev/null || true
            fi
            
            echo "🖥️  桌面快捷方式已强制更新: $DESKTOP_FILE"
            break
        fi
    done
    
    # 更新缓存
    if command -v gtk-update-icon-cache >/dev/null 2>&1; then
        gtk-update-icon-cache "$HOME/.local/share/icons/hicolor" 2>/dev/null || true
        echo "🔄 图标缓存已更新"
    fi
    
    if command -v update-desktop-database >/dev/null 2>&1; then
        update-desktop-database "$APPS_DIR" 2>/dev/null || true
        echo "🔄 桌面数据库已更新"
    fi
    
    echo "✅ 桌面集成完成！"
fi

# 启动应用程序
APP_EXECUTABLE="$HERE/usr/bin/$APPNAME"
if [ -x "$APP_EXECUTABLE" ]; then
    exec "$APP_EXECUTABLE" "$@"
else
    echo "❌ 错误：找不到可执行文件 $APPNAME"
    exit 1
fi
APPRUN_EOF

# 替换占位符
sed -i "s/APP_NAME_PLACEHOLDER/$APP_BASE_NAME/g" "$APPDIR/AppRun"

chmod +x "$APPDIR/AppRun"
echo "✅ 自定义 AppRun 已创建"

# --- 6. 使用 appimagetool 打包 ---
echo "📦 使用 appimagetool 打包应用..."
if appimagetool "$APPDIR" "$OUTPUT_FILE"; then
    echo "✅ appimagetool 打包成功"
else
    echo "❌ appimagetool 打包失败"
    exit 1
fi

# --- 7. 清理临时文件 ---
rm -rf "$APPDIR" 2>/dev/null || true

# --- 最终检查和输出 ---
if [ -f "$OUTPUT_FILE" ]; then
    chmod +x "$OUTPUT_FILE"
    FILE_SIZE=$(du -h "$OUTPUT_FILE" | cut -f1)
    
    echo ""
    echo "🎉 ========================================"
    echo "✅ AppImage 创建成功！"
    echo "======================================== 🎉"
    echo ""
    echo "📁 输出文件: $(pwd)/$OUTPUT_FILE"
    echo "📊 文件大小: $FILE_SIZE"
    echo "🎨 包含图标: $ICON_FILE"
    echo ""
    echo "🚀 分发说明："
    echo "1. 将 $OUTPUT_FILE 发送给用户"
    echo "2. 用户双击运行即可（首次会自动设置桌面集成）"
    echo "3. 桌面和程序菜单会自动出现 $APP_NAME 图标"
    echo "4. 之后可以直接双击桌面图标或从程序菜单启动"
    echo ""
    echo "💡 用户使用步骤："
    echo "   1. 下载 $OUTPUT_FILE 到任意目录"  
    echo "   2. 双击运行（如需要：右键 → 属性 → 权限 → 勾选'允许执行'）"
    echo "   3. 首次运行会自动创建桌面快捷方式和程序菜单项"
    echo "   4. 之后可直接双击桌面上的 $APP_NAME 图标启动"
    echo ""
    echo "✨ 只需要发送这一个文件！用户体验完美！"
else
    echo "❌ 创建失败！"
    exit 1
fi
)SCRIPT";
    
    QFile file(scriptPath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QMessageBox::critical(nullptr, "错误", 
            QString("无法创建临时非Qt脚本文件:\n%1").arg(scriptPath));
        return;
    }
    
    QTextStream out(&file);
    out << scriptContent;
    file.close();
}
#endif
